import { openDB } from 'idb';
import mock from '@/mock/mockInstance';
import { zh_CN, Faker } from '@faker-js/faker';
import { randomCarNumber, formatDateTime } from '@/utils/utils';

const customFaker = new Faker({ locale: zh_CN });

/**
 * 生成指定条数的数据，同时将数据写入数据库
 * @param num 生成的数据条数
 * @returns
 */
mock.onPost('/examplePage/StandardPage/generateDatas').reply(async (config) => {
  const { num } = JSON.parse(config.data);
  const data = [];

  // 打开数据库连接
  const dbPromise = openDB('examplePage', 1, {
    upgrade(db) {
      if (!db.objectStoreNames.contains('CurdStandardPage')) {
        db.createObjectStore('CurdStandardPage', { keyPath: 'id', autoIncrement: true });
      }
    }
  });

  const db = await dbPromise;

  // 获取数据库中的数据条数
  const count = (await db.count('CurdStandardPage')) || 0;

  // 如果数据库中的数据条数已经达到200条，直接返回一个特殊的响应
  if (count >= 200) {
    return [
      200,
      {
        code: 400,
        msg: '数据库中的数据已达到上限，无法再添加数据',
        data: []
      }
    ];
  }

  // 计算还能添加的数据条数
  const addNum = Math.min(num, 200 - count);

  for (let i = 0; i < addNum; i++) {
    data.push({
      driverName: customFaker.person.fullName(),
      driverPhone: customFaker.phone.number(),
      carNumber: randomCarNumber(),
      carType: customFaker.helpers.arrayElement(['小型车', '中型车', '大型车']),
      isMeasure: customFaker.helpers.arrayElement([0, 1]),
      inDate: formatDateTime(customFaker.date.past()),
      outDate: formatDateTime(customFaker.date.future()),
      createTime: formatDateTime(customFaker.date.recent(), true),
      weightTime: formatDateTime(customFaker.date.recent(), true),
      updateTime: formatDateTime(customFaker.date.recent(), true)
    });
  }

  // 将数据写入数据库
  const tx = db.transaction('CurdStandardPage', 'readwrite');
  data.forEach((item) => {
    tx.store.add(item);
  });

  const params = {
    code: 200,
    msg: '生成数据成功',
    data
  };
  return [200, params];
});

const matchQuery = (item: Record<string, any>, queryData: Record<string, any>) => {
  for (const key in queryData) {
    const queryValue = queryData[key];
    const itemValue = item[key];
    // 如果查询值为空，那么我们认为所有的数据都满足这个查询条件
    if (queryValue === null || queryValue === undefined || queryValue === '') {
      continue;
    }
    if (Array.isArray(queryValue)) {
      // 如果查询值是一个数组，那么我们认为它是一个时间范围
      // 我们将查询值中的开始和结束时间转换为时间戳，然后检查项目值是否在这个范围内
      const [start, end] = queryValue.map((date) => new Date(date).getTime());
      const itemTime = new Date(itemValue).getTime();
      if (itemTime < start || itemTime > end) {
        return false;
      }
    } else if (typeof queryValue === 'string') {
      // 如果查询值是一个字符串，我们做模糊匹配
      if (!itemValue.includes(queryValue)) {
        return false;
      }
    } else {
      // 其他类型的值，我们做严格相等比较
      if (itemValue !== queryValue) {
        return false;
      }
    }
  }
  return true;
};

/**
 * 查询数据
 * @param queryData 查询条件
 * @returns
 */
mock.onPost('/examplePage/StandardPage/query').reply(async (config) => {
  const { currentPage, pageSize, queryData } = JSON.parse(config.data);
  const dbPromise = openDB('examplePage', 1, {
    upgrade(db) {
      if (!db.objectStoreNames.contains('CurdStandardPage')) {
        db.createObjectStore('CurdStandardPage', { keyPath: 'id', autoIncrement: true });
      }
    }
  });

  const db = await dbPromise;
  const tx = db.transaction('CurdStandardPage', 'readonly');
  const store = tx.objectStore('CurdStandardPage');

  const results = [];
  let cursor = await store.openCursor();

  while (cursor) {
    if (matchQuery(cursor.value, queryData)) {
      results.push(cursor.value);
    }
    cursor = await cursor.continue();
  }
  results.reverse();

  // 分页处理
  const start = (currentPage - 1) * pageSize;
  const end = start + pageSize;
  const pagedResults = results.slice(start, end);
  const result = {
    code: 200,
    msg: 'success',
    total: results.length,
    data: pagedResults
  };

  return [200, result];
});

/**
 * 删除数据
 * @param id 要删除的数据的id
 * @returns
 */
mock.onPost('/examplePage/StandardPage/delete').reply(async (config) => {
  const { id } = JSON.parse(config.data);

  const dbPromise = openDB('examplePage', 1, {
    upgrade(db) {
      if (!db.objectStoreNames.contains('CurdStandardPage')) {
        db.createObjectStore('CurdStandardPage', { keyPath: 'id', autoIncrement: true });
      }
    }
  });

  const db = await dbPromise;
  const tx = db.transaction('CurdStandardPage', 'readwrite');
  const store = tx.objectStore('CurdStandardPage');

  await store.delete(id);

  const result = {
    code: 200,
    msg: '删除成功'
  };
  return [200, result];
});

/**
 * 新增或编辑数据
 * @param id 要编辑的数据的id，如果是新增操作，id为null
 * @param driverName 司机姓名
 * @param driverPhone 司机电话
 * @param carNumber 车牌号
 * @param carType 车型
 * @param isMeasure 是否过磅
 * @returns
 */
mock.onPost('/examplePage/StandardPage/modify').reply(async (config) => {
  const { id, driverName, driverPhone, carNumber, carType, isMeasure } = JSON.parse(config.data);

  const dbPromise = openDB('examplePage', 1, {
    upgrade(db) {
      if (!db.objectStoreNames.contains('CurdStandardPage')) {
        db.createObjectStore('CurdStandardPage', { keyPath: 'id', autoIncrement: true });
      }
    }
  });

  const db = await dbPromise;
  const tx = db.transaction('CurdStandardPage', 'readwrite');
  const store = tx.objectStore('CurdStandardPage');

  if (id === null) {
    // 新增操作
    const newData = {
      driverName,
      driverPhone,
      carNumber,
      carType,
      isMeasure,
      inDate: formatDateTime(customFaker.date.past()),
      outDate: formatDateTime(customFaker.date.future()),
      createTime: formatDateTime(customFaker.date.recent(), true),
      weightTime: formatDateTime(customFaker.date.recent(), true),
      updateTime: formatDateTime(customFaker.date.recent(), true)
    };
    await store.add(newData);
  } else {
    // 编辑操作
    let data = await store.get(id);
    data = { ...data, driverName, driverPhone, carNumber, carType, isMeasure };
    await store.put(data);
  }

  const result = {
    code: 200,
    msg: '操作成功'
  };
  return [200, result];
});
